import os
import sys
import glob
import pandas as pd
import subprocess
import signal
import configparser
import time
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTableWidget, QTableWidgetItem, 
                          QPushButton, QVBoxLayout, QHBoxLayout, QWidget, QTabWidget,
                          QLabel, QHeaderView, QMessageBox, QFileDialog, QGroupBox)
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QFont, QColor, QIcon

class GoldPriceViewer(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("金价数据监控工具")
        self.setGeometry(100, 100, 900, 600)
        
        # 初始化监控进程
        self.monitor_process = None
        
        # 创建中心部件
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        
        # 创建主布局
        self.main_layout = QVBoxLayout(self.central_widget)
        
        # 创建标题标签
        self.title_label = QLabel("金价实时监控工具")
        title_font = QFont()
        title_font.setPointSize(16)
        title_font.setBold(True)
        self.title_label.setFont(title_font)
        self.title_label.setAlignment(Qt.AlignCenter)
        self.main_layout.addWidget(self.title_label)
        
        # 创建信息区域
        self.info_layout = QHBoxLayout()
        self.update_time_label = QLabel("最后更新: 未获取")
        self.data_source_label = QLabel("数据来源: 金价网")
        self.status_label = QLabel("状态: 未运行")
        self.status_label.setStyleSheet("color: gray;")
        self.info_layout.addWidget(self.update_time_label)
        self.info_layout.addStretch(1)
        self.info_layout.addWidget(self.status_label)
        self.info_layout.addWidget(self.data_source_label)
        self.main_layout.addLayout(self.info_layout)
        
        # 创建控制面板
        self.control_group = QGroupBox("监控控制")
        self.control_layout = QHBoxLayout()
        self.control_group.setLayout(self.control_layout)
        
        # 创建启动按钮
        self.start_button = QPushButton("启动金价监控")
        self.start_button.setStyleSheet("background-color: #4CAF50; color: white; font-weight: bold;")
        self.start_button.clicked.connect(self.start_monitor)
        
        # 创建停止按钮
        self.stop_button = QPushButton("停止监控")
        self.stop_button.setStyleSheet("background-color: #f44336; color: white; font-weight: bold;")
        self.stop_button.clicked.connect(self.stop_monitor)
        self.stop_button.setEnabled(False)
        
        # 创建刷新按钮
        self.refresh_button = QPushButton("刷新数据")
        self.refresh_button.clicked.connect(self.load_latest_data)
        
        # 创建查看历史按钮
        self.history_button = QPushButton("查看历史数据")
        self.history_button.clicked.connect(self.open_history_file)
        
        # 添加按钮到控制面板
        self.control_layout.addWidget(self.start_button)
        self.control_layout.addWidget(self.stop_button)
        self.control_layout.addWidget(self.refresh_button)
        self.control_layout.addWidget(self.history_button)
        
        # 添加控制面板到主布局
        self.main_layout.addWidget(self.control_group)
        
        # 创建标签页
        self.tab_widget = QTabWidget()
        self.main_layout.addWidget(self.tab_widget)
        
        # 创建表格
        self.domestic_table = QTableWidget()
        self.international_table = QTableWidget()
        self.bank_table = QTableWidget()
        
        # 添加表格到标签页
        self.tab_widget.addTab(self.domestic_table, "国内金价")
        self.tab_widget.addTab(self.international_table, "国际金价")
        self.tab_widget.addTab(self.bank_table, "银行金价")
        
        # 读取配置信息
        self.load_config()
        
        # 设置自动刷新计时器
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.load_latest_data)
        self.timer.start(30000)  # 每30秒刷新一次
        
        # 创建状态栏
        self.statusBar().showMessage("准备就绪")
        
        # 加载最新数据
        self.load_latest_data()
        
        # 检查是否已有监控进程在运行
        self.check_running_monitor()
    
    def load_config(self):
        """读取配置文件信息"""
        try:
            if os.path.exists('config.ini'):
                config = configparser.ConfigParser()
                config.read('config.ini', encoding='utf-8')
                
                # 获取数据间隔时间
                interval = config.getint('Settings', 'fetch_interval_minutes')
                data_path = config.get('Settings', 'data_save_path')
                
                # 更新状态栏显示配置信息
                self.statusBar().showMessage(f"配置: 数据间隔 {interval} 分钟, 保存路径: {data_path}")
        except Exception as e:
            self.statusBar().showMessage(f"读取配置文件出错: {e}")
    
    def check_running_monitor(self):
        """检查是否已有监控进程在运行"""
        try:
            # 这里实现一个简单的检测方法，检查是否有最近的日志文件
            if os.path.exists('gold_tracker.log'):
                log_mtime = os.path.getmtime('gold_tracker.log')
                current_time = time.time()
                
                # 如果日志文件在过去5分钟内有更新，认为进程正在运行
                if current_time - log_mtime < 300:  # 5分钟 = 300秒
                    self.status_label.setText("状态: 正在运行")
                    self.status_label.setStyleSheet("color: green; font-weight: bold;")
                    self.start_button.setEnabled(False)
                    self.stop_button.setEnabled(True)
        except:
            pass
    
    def get_latest_file(self):
        """获取最新的金价数据文件"""
        try:
            # 读取配置中的数据保存路径
            config = configparser.ConfigParser()
            if os.path.exists('config.ini'):
                config.read('config.ini', encoding='utf-8')
                data_save_path = config.get('Settings', 'data_save_path')
            else:
                data_save_path = 'gold_data'
            
            # 确保目录存在
            if not os.path.exists(data_save_path):
                return None
                
            # 查找最新文件
            files = glob.glob(f"{data_save_path}/gold_price_*.xlsx")
            if not files:
                return None
            
            latest_file = max(files, key=os.path.getctime)
            return latest_file
        except Exception as e:
            self.statusBar().showMessage(f"获取最新文件出错: {e}")
            return None
    
    def load_latest_data(self):
        """加载最新的金价数据"""
        latest_file = self.get_latest_file()
        if not latest_file:
            self.statusBar().showMessage("未找到金价数据文件")
            return
        
        try:
            # 读取Excel文件
            excel_file = pd.ExcelFile(latest_file)
            sheet_names = excel_file.sheet_names
            
            # 获取各表格数据
            if "国内金价" in sheet_names:
                domestic_data = pd.read_excel(latest_file, sheet_name="国内金价")
                self.update_table(self.domestic_table, domestic_data)
            
            if "国际金价" in sheet_names:
                intl_data = pd.read_excel(latest_file, sheet_name="国际金价")
                self.update_table(self.international_table, intl_data)
            
            if "银行金价" in sheet_names:
                bank_data = pd.read_excel(latest_file, sheet_name="银行金价")
                self.update_table(self.bank_table, bank_data)
            
            # 更新信息
            if "数据信息" in sheet_names:
                info_data = pd.read_excel(latest_file, sheet_name="数据信息")
                if not info_data.empty and "数据时间" in info_data.columns:
                    self.update_time_label.setText(f"最后更新: {info_data['数据时间'][0]}")
                    
                    # 如果监控正在运行，检查最后更新时间
                    if self.monitor_process is not None:
                        last_update = pd.to_datetime(info_data['数据时间'][0])
                        now = pd.to_datetime(pd.Timestamp.now())
                        
                        # 如果最后更新时间超过10分钟，显示警告
                        if (now - last_update).total_seconds() > 600:  # 10分钟
                            self.status_label.setText("状态: 可能已停止")
                            self.status_label.setStyleSheet("color: orange; font-weight: bold;")
            
            self.statusBar().showMessage(f"已加载: {os.path.basename(latest_file)}", 3000)
        
        except Exception as e:
            self.statusBar().showMessage(f"加载数据失败: {e}")
    
    def update_table(self, table, data):
        """更新表格数据"""
        if data.empty:
            return
        
        # 设置列数和行数
        table.setColumnCount(len(data.columns))
        table.setRowCount(len(data))
        
        # 设置表头
        table.setHorizontalHeaderLabels(data.columns)
        
        # 填充数据
        for row in range(len(data)):
            for col in range(len(data.columns)):
                value = data.iloc[row, col]
                item = QTableWidgetItem(str(value))
                
                # 设置涨跌颜色
                if isinstance(value, str):
                    if "+" in value:  # 上涨
                        item.setForeground(QColor(255, 0, 0))  # 红色
                    elif "-" in value:  # 下跌
                        item.setForeground(QColor(0, 128, 0))  # 绿色
                
                table.setItem(row, col, item)
        
        # 调整列宽
        table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        
        # 设置表格只读
        table.setEditTriggers(QTableWidget.NoEditTriggers)
    
    def start_monitor(self):
        """启动金价监控程序"""
        if self.monitor_process is not None:
            QMessageBox.warning(self, "警告", "金价监控已经在运行中")
            return
        
        try:
            # 启动监控进程
            startupinfo = None
            if os.name == 'nt':  # Windows系统
                startupinfo = subprocess.STARTUPINFO()
                startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
                self.monitor_process = subprocess.Popen(
                    ["python", "gold_price_tracker.py"],
                    startupinfo=startupinfo,
                    stderr=subprocess.PIPE,
                    stdout=subprocess.PIPE
                )
            else:  # Linux/Mac系统
                self.monitor_process = subprocess.Popen(
                    ["python", "gold_price_tracker.py"],
                    stderr=subprocess.PIPE,
                    stdout=subprocess.PIPE
                )
            
            # 更新UI状态
            self.status_label.setText("状态: 正在运行")
            self.status_label.setStyleSheet("color: green; font-weight: bold;")
            self.start_button.setEnabled(False)
            self.stop_button.setEnabled(True)
            
            self.statusBar().showMessage("金价监控已启动")
            
            # 延迟3秒后刷新数据
            QTimer.singleShot(3000, self.load_latest_data)
            
        except Exception as e:
            self.statusBar().showMessage(f"启动金价监控失败: {e}")
            QMessageBox.critical(self, "错误", f"启动金价监控失败: {e}")
    
    def stop_monitor(self):
        """停止金价监控程序"""
        if self.monitor_process is None:
            QMessageBox.warning(self, "警告", "金价监控未在运行")
            return
        
        try:
            # 停止监控进程
            if os.name == 'nt':  # Windows系统
                subprocess.call(['taskkill', '/F', '/T', '/PID', str(self.monitor_process.pid)])
            else:  # Linux/Mac系统
                os.kill(self.monitor_process.pid, signal.SIGTERM)
            
            # 重置进程对象
            self.monitor_process = None
            
            # 更新UI状态
            self.status_label.setText("状态: 已停止")
            self.status_label.setStyleSheet("color: red;")
            self.start_button.setEnabled(True)
            self.stop_button.setEnabled(False)
            
            self.statusBar().showMessage("金价监控已停止")
            
        except Exception as e:
            self.statusBar().showMessage(f"停止金价监控失败: {e}")
            QMessageBox.critical(self, "错误", f"停止金价监控失败: {e}")
    
    def open_history_file(self):
        """打开历史数据文件"""
        try:
            # 读取配置中的数据保存路径
            config = configparser.ConfigParser()
            if os.path.exists('config.ini'):
                config.read('config.ini', encoding='utf-8')
                data_save_path = config.get('Settings', 'data_save_path')
            else:
                data_save_path = 'gold_data'
            
            data_dir = os.path.join(os.getcwd(), data_save_path)
            if not os.path.exists(data_dir):
                QMessageBox.warning(self, "提示", f"未找到数据目录: {data_dir}")
                return
            
            file_path, _ = QFileDialog.getOpenFileName(
                self, 
                "选择历史数据文件", 
                data_dir, 
                "Excel Files (*.xlsx)"
            )
            
            if file_path:
                try:
                    # 读取Excel文件
                    excel_file = pd.ExcelFile(file_path)
                    sheet_names = excel_file.sheet_names
                    
                    # 获取各表格数据
                    if "国内金价" in sheet_names:
                        domestic_data = pd.read_excel(file_path, sheet_name="国内金价")
                        self.update_table(self.domestic_table, domestic_data)
                    
                    if "国际金价" in sheet_names:
                        intl_data = pd.read_excel(file_path, sheet_name="国际金价")
                        self.update_table(self.international_table, intl_data)
                    
                    if "银行金价" in sheet_names:
                        bank_data = pd.read_excel(file_path, sheet_name="银行金价")
                        self.update_table(self.bank_table, bank_data)
                    
                    # 更新信息
                    if "数据信息" in sheet_names:
                        info_data = pd.read_excel(file_path, sheet_name="数据信息")
                        if not info_data.empty and "数据时间" in info_data.columns:
                            self.update_time_label.setText(f"最后更新: {info_data['数据时间'][0]}")
                    
                    self.statusBar().showMessage(f"已加载历史数据: {os.path.basename(file_path)}", 3000)
                
                except Exception as e:
                    self.statusBar().showMessage(f"加载历史数据失败: {e}")
                    QMessageBox.critical(self, "错误", f"加载历史数据失败: {e}")
        except Exception as e:
            self.statusBar().showMessage(f"打开历史文件出错: {e}")
    
    def closeEvent(self, event):
        """窗口关闭事件，提示是否关闭正在运行的监控"""
        if self.monitor_process is not None:
            reply = QMessageBox.question(
                self, '确认退出', 
                "金价监控正在运行中，关闭窗口将停止监控。\n是否继续退出？",
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No
            )
            
            if reply == QMessageBox.Yes:
                self.stop_monitor()
                event.accept()
            else:
                event.ignore()
        else:
            event.accept()

def main():
    app = QApplication(sys.argv)
    window = GoldPriceViewer()
    window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main() 